package com.krui.iweibo.service.parseweibo;

import java.io.FileNotFoundException;
import java.lang.Thread.State;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;

import com.krui.iweibo.utils.emotion.EmotionParse;

public class WeiboHelper {
	
	
	private static final String START="start";
	private static final String END="end";
	private static final String PHRASE="phrase";
	
	private static final String PATTERN_URL = "[a-zA-z]+://[^\\s]*";
	private static final String PATTERN_TOPIC="#.+?#";//话题
	private static final String PATTERN_NAMES="@([\u4e00-\u9fa5A-Za-z0-9_-]*)?";//人名
	private static final String PATTERN_EMOTION="\\[[\u4e00-\u9fa5A-Za-z0-9]*\\]";//表情
	public static final String EXTRA_SPANNABLE = "spannable";
	public static final String EXTRA_WEIBO = "weibo";
	private static final int WEIBO_PARSER_MSG = 1;
	private EmotionParse emotionParse = new EmotionParse();
	private WeiboCallbackManager callbackManager = new WeiboCallbackManager();
	
	private BlockingQueue<String> weiboQueue = new ArrayBlockingQueue<String>(50);
	private ParseThread parseThread  = new ParseThread();
	
	
	Handler handler = new Handler(){
		
		public void handleMessage(Message msg) {
		
			switch (msg.what) {
			
			case WEIBO_PARSER_MSG:
				
				Bundle bundle = msg.getData();
				String weibo = bundle.getString(EXTRA_WEIBO);
				SpannableStringBuilder spannable = (SpannableStringBuilder) bundle.getCharSequence(EXTRA_SPANNABLE);
				
				callbackManager.get(weibo, spannable);
				
				break;

			default:
				break;
			}
		};
	};
	
	
	public SpannableStringBuilder parseWeibo(String weibo,WeiboParseCallback callback){
		
		SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(weibo);
		
		//把要解析的微博跟回调接口先传入map中
		callbackManager.put(weibo, callback);
		
		startParserThread(weibo);
		
		return spannableStringBuilder;
		
	}
	
	
	/**
	 * 开始线程
	 * @param weibo
	 */
	private void startParserThread(String weibo) {
		if (weibo != null) {
			putWeiboToQueue(weibo);
		}
		
		State state = parseThread.getState();
		
		if (state == State.NEW) {
			parseThread.start();
		}else if (state == State.TERMINATED) {
			parseThread = new ParseThread();
			parseThread.start();
			
		}
		
	}


	/**
	 * 将解析数据加入线程队列中
	 * @param weibo
	 */
	private void putWeiboToQueue(String weibo) {
		
		try {
			if (!weiboQueue.contains(weibo)) {
				
				synchronized (this) {
					weiboQueue.put(weibo);
				}
			}
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
		
	}


	/**
	 * 解析微博(放于线程中避免ANR)
	 * @param weibo
	 * @return
	 * @throws FileNotFoundException 
	 */
	public SpannableStringBuilder parseWeibo(String weibo) throws FileNotFoundException
	{
		
		SpannableStringBuilder spannable = new SpannableStringBuilder(weibo);
		
		replaceWeibo(weibo,PATTERN_URL,spannable,false);
		replaceWeibo(weibo,PATTERN_TOPIC,spannable,false);
		replaceWeibo(weibo,PATTERN_NAMES,spannable,false);
		replaceWeibo(weibo,PATTERN_EMOTION,spannable,true);
		
		return spannable;
	}
	
	
	
	/**
	 * 解析微博 实现高亮
	 * @param weibo 要解析的微博
	 * @param regx 正则表达式
	 * @param spBuilder 
	 * @throws FileNotFoundException 
	 * @emotion 是否解析表情
	 * 
	 */
	public void replaceWeibo(String weibo,String regx,SpannableStringBuilder spBuilder,boolean emotion) throws FileNotFoundException{
		
		Pattern pattern = Pattern.compile(regx);
		
		List<HashMap<String, String>> list = getStartAndEnd(pattern, weibo);
		
		if (list != null) {
			for(HashMap<String, String> map : list){
				int start = Integer.parseInt(map.get(START));
				int end = Integer.parseInt(map.get(END));
				if (emotion) {//解析表情
					String phrse = map.get(PHRASE);
					Drawable drawable = emotionParse.getEmotionByPhrse(phrse);
					if (drawable != null) {
						drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
					}else {
						throw new FileNotFoundException("there have no emotion " + phrse + "in local filesys");
					}
					
					
					ImageSpan imgSpan = new ImageSpan(drawable);
					
					spBuilder.setSpan(imgSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				}else {
					ForegroundColorSpan fColorSpan = new ForegroundColorSpan(Color.parseColor("#63B8FF"));
					spBuilder.setSpan(fColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				}
			}
		}
		
		
	}
	
	/**
	 * 得到要解析字符的始末位置
	 * @param pattern
	 * @param weibo
	 * @return
	 */
	public List<HashMap<String, String>>  getStartAndEnd(Pattern pattern,String weibo)
	{
		
		List<HashMap<String, String>> lst = new ArrayList<HashMap<String,String>>();
		
		Matcher matcher = pattern.matcher(weibo);
		
		while(matcher.find())
		{
			
			HashMap<String, String> map = new HashMap<String, String>();
			
			map.put(PHRASE, matcher.group());
			map.put(START, matcher.start()+"");
			map.put(END, matcher.end()+"");
			
			lst.add(map);
		}
		
		return lst;
		
	}
	
	
	/**
	 * 解析线程
	 * @author krui
	 *
	 */
	private class ParseThread extends Thread{
		
		boolean isRun = true;
		
		@Override
		public void run() {
			try {
				
				while(isRun){
					String weibo  = weiboQueue.poll();
					if (weibo == null) return;
					
					SpannableStringBuilder spannable = parseWeibo(weibo);
					Message msg = handler.obtainMessage(WEIBO_PARSER_MSG);
					
					Bundle bundle = msg.getData();
					bundle.putString(EXTRA_WEIBO, weibo);
					bundle.putCharSequence(EXTRA_SPANNABLE, spannable);
					
					handler.sendMessage(msg);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				isRun = false;
			}
		}
	}
	

}
